/**
 * PHOSIDE: PHosphorylation Site IDentification Engine.
 * Copyright 2009 Digital Biology Lab, University of Missouri.
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version. <p/> This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more
 * details.
 */

package phoside.miscellaneous.io;

import java.io.IOException;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import phoside.PhosphoProteins;

import phoside.classify.result.PhosidePredictionResult;
import phoside.classify.result.PhosidePredictionResultImpl;

import phoside.io.ProteinsReader;
import phoside.io.xml.PhosideXmlProteinsReader;
import phoside.io.xml.PhosphoProteinFieldValueFormatter;

import phoside.util.IOUtil;

/**
 *
 * @author gjj
 */
public class PhosphoReaderPeptideReport implements ProteinsReader {
    private PhosidePredictionResult data;
    private String dirReport;

    public PhosphoReaderPeptideReport(String dirReport, PhosidePredictionResult data) {
        this.data = data;
        this.dirReport = dirReport;
    }

    public PhosphoProteins read() throws IOException {
        List<String> lines = IOUtil.readStringListAscii(dirReport);
        String acc = null;
        String seq = null;
        int n = lines.size();
        for (int i=0; i<n; i++) {
            String line = lines.get(i).trim();
            if (line.startsWith(">")) {
                acc = line.substring(1);
                phoside.Protein protein = data.getProtein(acc);
                if (protein==null) {
                    System.err.println(acc);
                    //System.exit(1);
                    continue;
                }

                seq = protein.getSequence();
//                int ix = acc.indexOf('|');
//                if (ix!=-1) {
//                    acc = acc.substring(0, ix);
//                }
            } else {
                if (seq==null) {
                    System.err.println(acc);
                }

                for (int site : getSites(seq,line)) {
                    data.addSite(acc, site);
                }
            }
        }
        return data;
    }

    public Set<Integer> getSites(String proteinSeq, String peptideSeq) {
        Set<Integer> siteSets = new HashSet<Integer>();
//        String AA = "ARNDCQEGHILKMFPSTWYVX";
//        AA += AA.toLowerCase();
        String AA = "A-Z";
        String seq = peptideSeq.toUpperCase().replaceAll("[^"+AA+"#]", "");
        String key = seq.replaceAll("#", "");
        int ig = proteinSeq.toUpperCase().indexOf(key);
        if (ig==-1) {
            System.err.println(peptideSeq+"@"+proteinSeq);
            return siteSets;
        }

        int index = seq.indexOf('#');
        while (index!=-1) {
            switch (seq.charAt(index-1)) {
                case 'S':
                case 'T':
                case 'Y': siteSets.add(ig+index-1); break;
                default: System.err.println("Wrong type of site!");
            }
            seq = seq.replaceFirst("#", "");
            index = seq.indexOf('#');
        }
        return siteSets;
    }

    public static void main(String[] args) {
//        String dir = "H:\\Phosphorylation Study\\090907 soybean stage 2-6 Fe and Ti\\mascot export 8ppm allmods\\dis\\";
//        List<String> files = phoside.util.IOUtil.listFilesInFolder(dir);
//        for (String file : files) {
//            if (file.endsWith("target.txt")) {
//                System.out.println(file);
//                if (!files.contains(file.substring(0, file.length()-4)+".xml"))
//                    main(dir+"\\"+file.substring(0, file.length()-4));
//            }
//        }

         String dir = "H:\\Phosphorylation Study\\PHOSIDE-analysis\\Arabidopsis-peptide";
         main(dir);
    }

    public static void main(String dirReport) {
//        String testXml = "H:\\Phosphorylation Study\\Brassica\\Bn_DFCIGI_Unigene_nr98.phoside-with-disorder.xml";
//        String dirReport = "H:\\Phosphorylation Study\\PHOSIDE-analysis\\brassica-peptide";
//        String testXml = "H:\\Phosphorylation Study\\Soybean\\Glyma.disorder.xml";
        String testXml = "H:\\Phosphorylation Study\\Arabidopsis\\TAIR9_pep_20090619.phoside-with-disorder.xml";
//        String dirReport = "H:\\Phosphorylation Study\\090907 soybean stage 2-6 Fe and Ti\\mascot export 8ppm allmods\\dis\\" +
//                "mascot_ti_allmods_ppm_-2_8_xc-z2-10_target";

//        Set<PhosphoProteins.PhosphoType> types = new HashSet();
//        types.add(PhosphoProteins.PhosphoType.SER);
//        types.add(PhosphoProteins.PhosphoType.THR);
//        types.add(PhosphoProteins.PhosphoType.TYR);

        PhosidePredictionResult data = new PhosidePredictionResultImpl(null);
        PhosideXmlProteinsReader readerxml = new PhosideXmlProteinsReader(testXml, data,
                new PhosphoProteinFieldValueFormatter());
        PhosphoReaderPeptideReport reader = new PhosphoReaderPeptideReport(dirReport, data);
        phoside.io.xml.PhosideXmlProteinsWriter writer
                = new phoside.io.xml.PhosideXmlProteinsWriter(dirReport+".xml",
                new phoside.io.xml.PhosideResultFieldValueFormatter());
        
        Set<PhosphoProteins.PhosphoType> types = new HashSet();
        types.add(PhosphoProteins.PhosphoType.SER);
        types.add(PhosphoProteins.PhosphoType.THR);

        try {
            readerxml.read();
//            for (String acc : data.getProteinsAccessions()) {
//                data.clearSites(acc);
//                data.getProtein(acc).removeInfo(phoside.util.StaticFinalValues.DISORDER);
//            }

            reader.read();

            phoside.ProteinFilter filter = new phoside.ProteinFilter() {
                public boolean filter(phoside.Protein protein) {
                    Set<Integer> sites = phoside.data.util.PhosphoDataUtil.getSites(protein);
                    return sites!=null && !sites.isEmpty();
                }
            };
            data.filterProteins(filter);

            writer.write(data);

            phoside.miscellaneous.test.FeatureEvaluation.main1(dirReport+".xml",dirReport+".disorder.feature",types);
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}
